﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lidgren.Network;

namespace uam_fps_game.Network
{
    public static class ServerManager
    {
        static NetPeerConfiguration config;
        static NetServer server;
        public static string mes = "";
        public static bool IsAlive = false;

        static List<Player> players;

        public static void Start()
        {
            players = new List<Player>();

            config = new NetPeerConfiguration("Configure");
            config.Port = 14242;

            server = new NetServer(config);
            server.Start();
            IsAlive = true;
        }

        public static void ShutDown()
        {
            server.Shutdown("Bye bye");
            IsAlive = false;
        }

        public static void SendMessage(string message, NetDeliveryMethod method)
        {
            NetOutgoingMessage sendMsg = server.CreateMessage();
            sendMsg.Write(message);
            server.SendMessage(sendMsg, server.Connections, method, 0);
        }

        public static void SendMessage(MessageTypes.Header header, MessageTypes.MessagePrototype message)
        {
            NetOutgoingMessage om = server.CreateMessage();
            if ((int)header < 10)
                om.WriteVariableInt32(0);
            om.WriteVariableInt32((int)header);
            message.CreateMessage(ref om);

            server.SendMessage(om, server.Connections, NetDeliveryMethod.ReliableOrdered, 0);
        }

        public static void SendMessage(MessageTypes.Header header, MessageTypes.MessagePrototype message, NetConnection con)
        {
            NetOutgoingMessage om = server.CreateMessage();
            if ((int)header < 10)
                om.WriteVariableInt32(0);
            om.WriteVariableInt32((int)header);
            message.CreateMessage(ref om);

            server.SendMessage(om, con, NetDeliveryMethod.ReliableOrdered, 0);
            
        }

        public static void Update()
        {
            if (IsAlive)
            {
                mes = "";
                NetIncomingMessage msg;
                while ((msg = server.ReadMessage()) != null)
                {
                    ReceiveMessage(msg, true);
                    server.Recycle(msg);
                }
            }
        }

        public static void ReceiveMessage(NetIncomingMessage msg, bool asServer)
        {
            if (msg.MessageType == NetIncomingMessageType.Data)
            {
                int head = msg.ReadVariableInt32() * 10 + msg.ReadVariableInt32();

                MessageTypes.Letter letter;
                if (asServer)
                {
                    switch (head)
                    {
                        case 0:
                            Player player = MessageTypes.AddPlayer.ParseMessage(msg);
                            player.NetConnection = msg.SenderConnection;
                            players.Add(player);
                            SendMessage(MessageTypes.Header.SendMessageToAll, new MessageTypes.SendMessageToAll("Server", " " + player.Name + " joined server!"));
                            break;
                        case 1:

                            string name = MessageTypes.RemovePlayer.ParseMessage(msg);

                            Player p = null;
                            int c = -1;

                            foreach (Player play in players)
                            {
                                if (play.Name.ToString() == name)
                                    p = play;
                            }
                            foreach (NetConnection con in server.Connections)
                            {
                                c++;
                                if (con == p.NetConnection)
                                    break;
                            }
                            if (p != null)
                                players.Remove(p);
                            SendMessage(MessageTypes.Header.SendMessageToAll, new MessageTypes.SendMessageToAll("Server", " " + p.Name + " has been removed from server."));

                            if (c != -1)
                                server.Connections[c].Disconnect("Papasie!");
                            break;
                        case 2:
                            break;
                        case 3:
                            letter = MessageTypes.SendMessageToAll.ParseMessage(msg);
                            SendMessage(MessageTypes.Header.SendMessageToAll, new MessageTypes.SendMessageToAll(letter.senderName, letter.text));
                            break;

                        case 4:
                            letter = MessageTypes.SendMessageToSmb.ParseMessage(msg);

                            Player pl1 = null;
                            foreach (Player play in players)
                                if (play.Name.ToString() == letter.receiverName)
                                    pl1 = play;
                            foreach (NetConnection con in server.Connections)
                                if (con == pl1.NetConnection)
                                {
                                    SendMessage(MessageTypes.Header.SendMessageToSmb, new MessageTypes.SendMessageToSmb(letter.senderName, letter.receiverName, letter.text), con);
                                    break;
                                }
                            break;
                        default:
                            break;
                    }
                }
               
            }

        }
        

    }
}
